home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / mweb / MWEB Utils / ws295sdk.exe / Ws2sdkzp.exe / SAMPLES / LAYERED / DASYNCW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-06-06  |  8.2 KB  |  376 lines

  1. /*++
  2.  
  3.      Copyright (c) 1996 Intel Corporation
  4.      Copyright (c) 1996 Microsoft Corporation
  5.      All Rights Reserved
  6.  
  7.      Permission is granted to use, copy and distribute this software and
  8.      its documentation for any purpose and without fee, provided, that
  9.      the above copyright notice and this statement appear in all copies.
  10.      Intel makes no representations about the suitability of this
  11.      software for any purpose.  This software is provided "AS IS."
  12.  
  13.      Intel specifically disclaims all warranties, express or implied,
  14.      and all liability, including consequential and other indirect
  15.      damages, for the use of this software, including liability for
  16.      infringement of any proprietary rights, and including the
  17.      warranties of merchantability and fitness for a particular purpose.
  18.      Intel does not assume any responsibility for any errors which may
  19.      appear in this software nor any responsibility to update it.
  20.  
  21.  
  22. Module Name:
  23.  
  24.  
  25. Abstract:
  26.  
  27.  
  28. --*/
  29.  
  30. #include "precomp.h"
  31.  
  32. #define INVALID_ASYNC_WINDOW ((HWND)-1)
  33. DWORD
  34. AsyncThreadProc(
  35.     DWORD  Context
  36.     )
  37. /*++
  38. Routine Description:
  39.  
  40.     Thread procedure passed to CreatThread().
  41.  
  42. Arguments:
  43.  
  44.     Context - Context value passed to CreateThread().  The context value is the
  45.               async thread object.
  46.  
  47. Return Value:
  48.  
  49.     The Return value of the worker thread
  50.  
  51. --*/
  52.  
  53. {
  54.     PDASYNCWINDOW             Thread;
  55.     HINSTANCE                 HModule;
  56.     MSG                       msg;
  57.  
  58.     HModule = LoadLibraryA (gLibraryName);
  59.     Thread = (PDASYNCWINDOW)Context;
  60.     if (Thread->CreateAsyncWindow ()==NO_ERROR) {
  61.         while(GetMessage( &msg, NULL, 0, 0 )== TRUE) {
  62.             TranslateMessage( &msg );
  63.             DispatchMessage( &msg );
  64.         }
  65.     }
  66.  
  67.     DEBUGF( DBG_TRACE,
  68.             ("Exiting async thread.\n"));
  69.     FreeLibraryAndExitThread (HModule, 0);
  70.     return 0;   // Keep compiler happy
  71. }
  72.  
  73. LRESULT
  74. CALLBACK
  75. AsyncWndProc(
  76.     HWND hwnd,
  77.     UINT msg,
  78.     WPARAM wParam,
  79.     LPARAM lParam
  80.     )
  81. {
  82.     PDASYNCWINDOW    Thread = (PDASYNCWINDOW)GetWindowLong (hwnd, 0);
  83.     if (Thread) {
  84.         BOOL             ReturnCode;
  85.  
  86.         ReturnCode = Thread->ProcessAsyncMessage (msg, (SOCKET)wParam, lParam);
  87.         if (ReturnCode==TRUE)
  88.             return 0;
  89.         else if (ReturnCode == -1)
  90.             delete Thread;
  91.     }
  92.  
  93.     return DefWindowProc(hwnd, msg, wParam, lParam);
  94. }
  95.  
  96.  
  97.  
  98.  
  99. DASYNCWINDOW::DASYNCWINDOW()
  100. /*++
  101. Routine Description:
  102.  
  103.     Creates any internal state.
  104.  
  105. Arguments:
  106.  
  107.     None
  108.  
  109. Return Value:
  110.  
  111.     None
  112.  
  113. --*/
  114.  
  115. {
  116.     m_async_thread = NULL;
  117.     m_async_window = NULL;
  118.     m_exit_thread = FALSE;
  119. }
  120.  
  121.  
  122.  
  123. DASYNCWINDOW::~DASYNCWINDOW()
  124. /*++
  125. Routine Description:
  126.  
  127.     destroys any internal state.
  128.  
  129. Arguments:
  130.  
  131.     None
  132.  
  133. Return Value:
  134.  
  135.     None
  136.  
  137. --*/
  138. {
  139.  
  140.     DEBUGF( DBG_TRACE,
  141.             ("Destroyed async thread object\n"));
  142. }
  143.  
  144.  
  145.  
  146. INT
  147. DASYNCWINDOW::Initialize(
  148.     )
  149. /*++
  150. Routine Description:
  151.  
  152.     Initializes the DASYNCWINDOW object.
  153.  
  154. Arguments:
  155.  
  156.     NONE
  157.  
  158. Return Value:
  159.  
  160.     If no error occurs, Initialize() returns NO_ERROR.  Otherwise the value
  161.     SOCKET_ERROR  is  returned,  and  a  specific  error  code  is available in
  162.     lpErrno.
  163.  
  164. --*/
  165. {
  166.     INT ReturnCode;
  167.     DWORD ThreadId;
  168.  
  169.     DEBUGF( DBG_TRACE,
  170.             ("Initializing async thread \n"));
  171.  
  172.  
  173.     //
  174.     // Create the worker thread and wait for the new thred to finish its
  175.     // initialization.
  176.     //
  177.     m_async_thread = CreateThread(
  178.         NULL,
  179.         0,
  180.         (LPTHREAD_START_ROUTINE)::AsyncThreadProc,
  181.         this,
  182.         0,
  183.         &ThreadId);
  184.     if (m_async_thread){
  185.         while (m_async_window==NULL)
  186.             Sleep (0);
  187.         if (m_async_window!=INVALID_ASYNC_WINDOW)
  188.             ReturnCode = NO_ERROR;
  189.         else
  190.             ReturnCode = WSAENOBUFS;
  191.     }
  192.     else {
  193.         ReturnCode = CreateAsyncWindow ();
  194.     }
  195.  
  196.     return ReturnCode;
  197.  
  198. } //Initailize
  199.  
  200. VOID
  201. DASYNCWINDOW::Destroy(
  202.     )
  203. /*++
  204. Routine Description:
  205.  
  206.     Initiates destruction of the DASYNCWINDOW object.
  207.     This can't be done syncronously in destructor because this
  208.     will require waiting for thread object to exit which we wont
  209.     to avoid.
  210.  
  211. Arguments:
  212.  
  213.     NONE
  214.  
  215. Return Value:
  216.  
  217.     NONE
  218. --*/
  219. {
  220.         // Just destroy the window and it will quit the thread
  221.         // if one exists
  222.     if ((m_async_window!=NULL) && (m_async_window!=INVALID_ASYNC_WINDOW)) {
  223.         m_exit_thread = TRUE;
  224.         DestroyWindow (m_async_window);
  225.     }
  226. }
  227.  
  228.  
  229. DWORD
  230. DASYNCWINDOW::CreateAsyncWindow (
  231.     )
  232. {
  233.     WNDCLASSA wndclass;
  234.  
  235.     //
  236.     // Register the window class if necessary.
  237.     //
  238.  
  239.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  240.     wndclass.lpfnWndProc = (WNDPROC)AsyncWndProc;
  241.     wndclass.cbClsExtra = 0;
  242.     wndclass.cbWndExtra = sizeof(PDASYNCWINDOW);
  243.     wndclass.hInstance = HDllInstance;
  244.     wndclass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
  245.     wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
  246.     wndclass.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
  247.     wndclass.lpszMenuName = NULL;
  248.     wndclass.lpszClassName = ASYNC_WINDOW_CLASS_NAME;
  249.  
  250.     if( RegisterClass( &wndclass ) == 0 ) {
  251.  
  252.         return WSAENOBUFS;
  253.  
  254.     }
  255.  
  256.  
  257.     //
  258.     // Create the window.
  259.     //
  260.  
  261.     m_async_window = CreateWindowA(
  262.                                 ASYNC_WINDOW_CLASS_NAME,    // lpszClassName
  263.                                 "",                         // lpszWindowName
  264.                                 WS_OVERLAPPEDWINDOW,        // dwStyle
  265.                                 CW_USEDEFAULT,              // x
  266.                                 CW_USEDEFAULT,              // y
  267.                                 CW_USEDEFAULT,              // nWidth
  268.                                 CW_USEDEFAULT,              // nHeight
  269.                                 NULL,                       // hwndParent
  270.                                 NULL,                       // hmenu
  271.                                 HDllInstance,               // hinst
  272.                                 NULL                        // lpvParam
  273.                                 );
  274.  
  275.     if( m_async_window != NULL ) {
  276.  
  277.         //
  278.         // Associate the async thread object with window.
  279.         //
  280.         SetWindowLong (m_async_window, 0, (DWORD)this);
  281.         return NO_ERROR;
  282.  
  283.     }
  284.     else {
  285.         m_async_window = INVALID_ASYNC_WINDOW;
  286.         return WSAENOBUFS;
  287.     }
  288.  
  289. }
  290.  
  291.  
  292. BOOL
  293. DASYNCWINDOW::ProcessAsyncMessage (
  294.     UINT    msg,
  295.     SOCKET  s,
  296.     LPARAM  param
  297.     ) {
  298.     PDSOCKET    Socket;
  299.  
  300.     if (!m_exit_thread) {
  301.         switch( msg ) {
  302.         case WM_SELECT_MESSAGE:
  303.             Socket = DSOCKET::FindDSocketFromProviderSocket (s);
  304.             if (Socket)
  305.                 Socket->SignalAsyncEvents (param);
  306.             return TRUE;
  307.  
  308.         case WM_DESTROY :
  309.  
  310.             if (m_async_thread) {
  311.                 PostThreadMessage (NULL, WM_QUIT, 0, 0);
  312.                 CloseHandle (m_async_thread);
  313.                 m_async_thread = NULL;
  314.                 DEBUGF (DBG_TRACE, ("Async thread received quit message.\n"));
  315.             }
  316.             return -1;
  317.         default:
  318.             return FALSE;
  319.         }
  320.     }
  321.     else {
  322.         if (m_async_thread) {
  323.             PostThreadMessage (NULL, WM_QUIT, 0, 0);
  324.             CloseHandle (m_async_thread);
  325.             m_async_thread = NULL;
  326.             DEBUGF (DBG_TRACE, ("Async thread exit flag set.\n"));
  327.         }
  328.         return -1;
  329.     }
  330. }
  331.  
  332. INT
  333. DASYNCWINDOW::RegisterSocket(
  334.     PDSOCKET Socket
  335.     )
  336. /*++
  337. Routine Description:
  338.  
  339.     Register the socket with provider to receive messages for async window
  340.     maintained by this async thread object
  341.     
  342. Arguments:
  343.  
  344.     Socket - A pointer to a DSOCKET object for the socket that is registering.
  345.  
  346. Return Value:
  347.  
  348.     On success NO_ERROR else a valid winsock error code.
  349.  
  350. --*/
  351. {
  352.     INT        ReturnCode;
  353.     LONG       SocketEventMask;
  354.     SOCKET     ProviderSocket;
  355.     PDPROVIDER Provider;
  356.  
  357.     // Get the info we need from the socket
  358.     ProviderSocket    = Socket->GetProviderSocket();
  359.     SocketEventMask = Socket->GetAsyncEventMask();
  360.     Provider        = Socket->GetDProvider();
  361.  
  362.     //Add the socket to the wait array
  363.     if (Provider->WSPAsyncSelect(
  364.             ProviderSocket,
  365.             m_async_window,
  366.             WM_SELECT_MESSAGE,
  367.             SocketEventMask,
  368.             &ReturnCode)==0)
  369.         return NO_ERROR;
  370.     else
  371.         return ReturnCode;
  372. }
  373.  
  374.  
  375.  
  376.